package com.yyfax.pay.quartz.jobs;

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yyfax.commons.lang.DateUtil;
import com.yyfax.framework.spring.ApplicationContextHolder;
import com.yyfax.pay.common.constants.PayConstants;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.enums.PayStepEnum;
import com.yyfax.pay.common.enums.QueryTypeEnum;
import com.yyfax.pay.common.enums.TaskStateEnum;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.order.data.service.QueryTaskService;
import com.yyfax.pay.order.model.po.PayOrderLogPO;
import com.yyfax.pay.order.model.po.QueryTaskPO;
import com.yyfax.pay.order.model.vo.PayOrderVO;
import com.yyfax.pay.order.service.PayService;
import com.yyfax.pay.quartz.model.vo.DynamicJobVO;

/**
 * 查询支付订单任务
 * 
 * @author jiangmy
 * @date 2017-04-18 15:53:28
 * @since v1.0.0
 */
public class QueryPayOrderJob implements Job {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	// services
	private QueryTaskService queryTaskService;
	private PayService payService;

	// biz data
	private QueryTaskPO task;
	private PayOrderVO order;
	private PayConstants payConstants;

	public void preInit(JobExecutionContext context) throws YYPayException {
		// services
		queryTaskService = ApplicationContextHolder.getBean(QueryTaskService.class);
		payService = ApplicationContextHolder.getBean(PayService.class);
		payConstants = ApplicationContextHolder.getBean(PayConstants.class);
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		logger.info("执行任务:{}", context);
		// 初始化环境
		try {
			preInit(context);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return;
		}

		// 初始化数据
		try {
			Object orderObj = context.getMergedJobDataMap().get(DynamicJobVO.ORDER_KEY);
			if (orderObj == null) {
				logger.warn("【定时任务失败,关闭任务】订单信息为空 {}", context.getJobDetail().getKey());
				return;
			}
			task = (QueryTaskPO) orderObj;
			order = payService.queryPayOrder(task.getOrderId(), task.getMerchantCode(), QueryTypeEnum.AUTO);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		// 更新task
		try {
			task.setLastTime(DateUtil.getCurrentDateTime());
			task.setOptNo(task.getOptNo() + 1);
			// 下次任务时间的算法,可以考虑调整
			task.setNextTime(DateUtil.datetime2Str(DateUtil.addSecond(new Date(), payConstants.getQueryTaskTime() * task.getOptNo())));

			PayOrderLogPO queryStep = order.getStepLast(PayStepEnum.STEP3_QUERY_RESULT);
			if (queryStep != null) { // 如果存在主动查询步骤
				// 如果主动查询状态为：成功、失败、订单不存在，则关闭主动查询任务
				if (PayRspCodeEnum.SUCCESS.isValue(queryStep.getResultCode()) || PayRspCodeEnum.PAY_CODE_PAY_FAIL.isValue(queryStep.getResultCode())
						|| PayRspCodeEnum.PAY_CODE_ORDER_NOT_FOUND.isValue(queryStep.getResultCode())) {
					task.setState(TaskStateEnum.SUCCESS.getValue());
					task.setRemark("查询成功,订单状态为：" + queryStep.getResultCode());
					return;
				}
			}

			PayOrderLogPO resultStep = order.getStepLast(PayStepEnum.STEP4_PAY_RESULT);
			if (resultStep != null) { // 如果存在结果异步回调步骤
				// 如果异步回调约定状态只有：成功、失败
				task.setState(TaskStateEnum.SUCCESS.getValue());
				task.setRemark("已经接收支付通道异步通知");
				return;
			}

			// 超次或者超时
			if (task.getOptNo() >= task.getMaxNo()
					|| (task.getEndTime() != null && task.getEndTime().compareTo(DateUtil.getCurrentDateTime()) <= 0)) {
				task.setState(TaskStateEnum.FAILED.getValue());
				task.setRemark("达到最大查询次数或时间");
				return;
			}

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			try {
				queryTaskService.updateTask(task);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		// 刷新任务
		try {
			refreshTask(context);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public void refreshTask(JobExecutionContext context) throws YYPayException {
		if (!TaskStateEnum.ACTIVE.isValue(task.getState())) {
			return;
		}
		DynamicJobVO dynamicJob = new DynamicJobVO(task);
		try {
			// 查询支付订单
			dynamicJob.target(getClass());
			dynamicJob.addOrderData(task);
			dynamicJob.cronExpression(DateUtil.date2Str(DateUtil.str2DateTime(task.getNextTime()), "s m H d M ? yyyy")); // "0 15 10 * * ? 2015"
																															// 2015年的每天早上10：15触发
			com.yyfax.pay.quartz.dynamic.DynamicSchedulerFactory.updateJob(dynamicJob);
		} catch (Exception e) {
			logger.error("【添加任务】", e);
		} finally {
			logger.info("【添加任务】{}", task);
			logger.info("【添加Quartz】{}", dynamicJob);
		}
	}
}